﻿#pragma once


#include <queue>
#include <optional>

namespace Base {

	class Mouse;
	class MouseEvent {
	public:

		enum class Type
		{
			LPress,
			LRelease,
			RPress,
			RRelease,
			//WheelUp,
			//WheelDown,
			Move,
			Enter,
			Leave,
		};

	public:
		MouseEvent(Type type, const Mouse* mouse);

		Type GetType()const { return type; }
		int GetX()const { return x; }
		int GetY() const { return y; }
		bool LeftIsPressed() const { return leftIsPressed; }
		bool RightIsPressed() const { return rightIsPressed; }

	private:
		Type type;
		bool leftIsPressed;
		bool rightIsPressed;
		int x;
		int y;
	};


	//---------------------------------------
	class Mouse
	{
		friend class MouseEvent;

	public:

		std::optional<MouseEvent> Read();
		bool IsInWindow() const { return isInWindow; }

	public:

		// callback
		void OnMouseMove(int newx, int newy);
		void OnMouseLeave();
		void OnMouseEnter();
		void OnLeftPressed(int newx, int newy);
		void OnLeftReleased(int x, int y);
		void OnRightPressed(int x, int y);
		void OnRightReleased(int x, int y);
		//void OnWheelUp(int x, int y);
		//void OnWheelDown(int x, int y);
		//void OnWheelDelta(int x, int y, int delta);
		void TrimBuffer();
	private:

		static constexpr unsigned int kBufferSize = 16;
		int x;
		int y;
		bool leftIsPressed = false;
		bool rightIsPressed = false;
		bool isInWindow = false;

		//int wheelDeltaCarry = 0;
		std::queue<MouseEvent> m_buffer;
	};

}
